package com.example.springframework.beans.factory;

import com.example.springframework.beans.BeansException;

/**
 * @fileName: {@link BeanFactory}
 * @author: yyfl
 * @date: 2023/2/23 14:54
 * @description:
 * @history:
 *
 * 主要作用是：统一了调用入口进行各种实现
 *
 * 第一步 先定义一个Bean工厂接口，实现的话由AbstractBeanFactory来实现
 *      这样统一使用模板模式的方式可以统一收口通用核心方法的调用逻辑和方法定义
 *      也就很好的控制了后续的实现者不用关心调用逻辑，按照统一方法执行，那么类的继承者只要关心具体方法的实现逻辑就行了
 */
public interface BeanFactory {

    /**
     * 获取Bean实例的统一入口
     *
     * @param name Bean名称
     * @return Bean实例
     */
    Object getBean(String name) throws BeansException;

    /**
     * （新）获取Bean实例的统一入口
     * 此方法是为了解决当UserService中有构造函数且需要传参的报错问题
     *
     * 参考 Spring Bean 容器源码的实现方式，在 BeanFactory 中添加 Object getBean(String name, Object... args) 接口，这样就可以在获取 Bean 时把构造函数的入参信息传递进去了。
     * 另外一个核心的内容是使用什么方式来创建含有构造函数的 Bean 对象呢？这里有两种方式可以选择，
     * 一个是基于 Java 本身自带的方法 DeclaredConstructor，
     * 另外一个是使用 Cglib 来动态创建 Bean 对象。Cglib 是基于字节码框架 ASM 实现，所以你也可以直接通过 ASM 操作指令码来创建对象
     *
     * @param name Bean名称
     * @return Bean实例
     */
    Object getBean(String name, Object... args) throws BeansException;

}
